package com.livestocksolutions.intent;

import java.util.Arrays;
import java.util.Date;

import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.livestocksolutions.Bovine;
import com.livestocksolutions.Group;
import com.livestocksolutions.Join;
import com.livestocksolutions.LivestockSolutions;
import com.livestocksolutions.Observation;
import com.livestocksolutions.R;
import com.livestocksolutions.ui.ListCattleArrayAdapter;
import com.livestocksolutions.ui.ListJoinArrayAdapter;
import com.livestocksolutions.ui.ListObservationArrayAdapter;
import com.livestocksolutions.ui.ViewCattleArrayAdapter;
import com.livestocksolutions.ui.ViewGroupArrayAdapter;
import com.livestocksolutions.ui.ViewGroupMobArrayAdapter;
import com.livestocksolutions.ui.ViewJoinArrayAdapter;
import com.livestocksolutions.ui.ViewObservationArrayAdapter;
import com.livestocksolutions.util.StringArrayParcelable;

/* -- Version History --
 *  1.0 : 09 September 2012 - Initial version. 
 */

/**
 * This class manages a Group object
 * @author Adam Parr
 * @version 1.0
 * 
 * @.modified 28 September 2012
 */
public class GroupActivity extends BaseActivity {
	public static final int GROUPVIEW		  = 0;
	public static final int OBSERVATIONVIEW	  = 1;
	public static final int JOINVIEW 	 = 2;
	/**
	 * Stores the reference to the XML layout template for each view
	 * @see #GROUPVIEW
	 * @see #OBSERVATIONVIEW
	 * @see #JOINVIEW
	 */
	public static final Integer[] RESOURCEID = new Integer[]{
		R.layout.item,
		R.layout.item,
		R.layout.item
	};
	
	/**
	 * Group View that holds the data of the Group
	 */
	protected ViewGroupMobArrayAdapter groupView;
	/**
	 * List of Cattle that holds the cattle for this Group
	 */
	protected ListCattleArrayAdapter cattle;
	/**
	 * List of Observations that holds the Observations of the Group
	 */
	protected ListObservationArrayAdapter observations;
	/**
	 * List of Joins that holds the Joining of the Mob
	 */
	protected ListJoinArrayAdapter joins;
	
	/**
	 * Constructor
	 */
	public GroupActivity() {
		super(RESOURCEID);
	}
	
	protected GroupActivity(Integer[] resourceID){
		super(resourceID);
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		if(stack.size()==0){
			setContentView(RESOURCEID[GROUPVIEW]);
			if(!built){
				// Put the ID of this Group Object
				id = id!=-1?id:getIntent().getExtras().getLong(ITEMID,-1);
				Group g = LivestockSolutions.getGroupByID(id);
				// Read initial state of the Group Object
				String[] groupType = new String[ViewGroupMobArrayAdapter.SIZE];
				groupType[ViewGroupMobArrayAdapter.ID]			 = String.valueOf(g.getID());
				groupType[ViewGroupMobArrayAdapter.NAME]		 = g.getName();
				groupType[ViewGroupMobArrayAdapter.DESCRIPTION] = g.getDescription();

				Bovine[] bovineList = g.getBovineList();
				Arrays.sort(bovineList, bovineComparator);
				String[][] cattleValues = new String[bovineList.length][];
				for(int x=0; x<bovineList.length; x++){
					Date dobDate =  bovineList[x].getDob();
					
					String[] item = new String[ListCattleArrayAdapter.SIZE];
					item[ViewCattleArrayAdapter.ID]=String.valueOf(bovineList[x].getID());
					item[ViewCattleArrayAdapter.VISUALID]=bovineList[x].getEartag().getEartagID();
					item[ViewCattleArrayAdapter.NLISRFID]=bovineList[x].getEartag().getRfID();
					item[ViewCattleArrayAdapter.DOB]=dobDate!=null?String.valueOf(dobDate.getTime()):"";
					
					cattleValues[x]=item;
				}
				
				Observation[] observationList = g.getObservations();
				Arrays.sort(observationList, observationComparator);
				String[][] observationValues = new String[observationList.length][];
				for(int x=0; x<observationList.length; x++){
					String[] item = new String[ViewObservationArrayAdapter.SIZE];
					item[ViewObservationArrayAdapter.ID]=String.valueOf(observationList[x].getID());
					item[ViewObservationArrayAdapter.DATE]=String.valueOf(observationList[x].getDate().getTime());
					item[ViewObservationArrayAdapter.TYPE]=String.valueOf(observationList[x].getPriority());
					item[ViewObservationArrayAdapter.VALUE]=observationList[x].getComment();
					
					observationValues[x]=item;
				}
				
				Join[] joinList = g.getCurrentJoinings();
	            Arrays.sort(joinList, joinComparator);
	            String[][] joinValues = new String[joinList.length][];
	            for(int x=0; x<joinList.length; x++){
	            	String[] item = new String[ViewJoinArrayAdapter.SIZE];
	            	item[ViewJoinArrayAdapter.ID]=String.valueOf(joinList[x].getID());
	            	item[ViewJoinArrayAdapter.INSERTIONDATE]=String.valueOf(joinList[x].getInsertionDate().getTime());
	            	item[ViewJoinArrayAdapter.REMOVALDATE]=String.valueOf(joinList[x].getRemovalDate().getTime());
	            	item[ViewJoinArrayAdapter.COUNT]=String.valueOf(joinList[x].getCows().length);
	    			
	            	joinValues[x]=item;
	            }
				
				groupView = new ViewGroupArrayAdapter(this, groupType);
				cattle = new ListCattleArrayAdapter(this, cattleValues);
				observations = new ListObservationArrayAdapter(this, observationValues);
				joins = new ListJoinArrayAdapter(this, joinValues);
				
				setPage();
				drawMembers();
				
				currentState.putInt(STATEID,GROUPVIEW);
				built=true;
			}
		}
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Show the menu for an Location Object
		getMenuInflater().inflate(R.menu.group_menu, menu);
		this.menu=menu;
		return true;
	}

	
	@Override
	public void onSaveInstanceState (Bundle outState) {
		super.onSaveInstanceState (outState);

		outState.putParcelable("groupType", new StringArrayParcelable().setStrings(groupView.get()));
		outState.putParcelable("groupMembers", new StringArrayParcelable().setStrings(cattle.get()));
		outState.putParcelable("groupObservation", new StringArrayParcelable().setStrings(observations.get()));
	}
	
	@Override
	public void onRestoreInstanceState(Bundle inState) {
		if(groupView==null){
			groupView = new ViewGroupArrayAdapter(this,((StringArrayParcelable)inState.getParcelable("groupType")).getStrings()[0]);
		}
		cattle = new ListCattleArrayAdapter(this,((StringArrayParcelable)inState.getParcelable("groupMembers")).getStrings());
		observations = new ListObservationArrayAdapter(this,((StringArrayParcelable)inState.getParcelable("groupObservation")).getStrings());

		super.onRestoreInstanceState (inState);
	}
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
		
	}
	
	@Override
	public boolean frameSelection(int frame) {
		switch (frame) {
			case R.id.menu_member:
				showView(GROUPVIEW,currentState);
				break;
			case R.id.menu_join:
        		showView(JOINVIEW,currentState);
        		break;
			case R.id.menu_add_observation:
				// Add a blank observation, Start a new Observation
				Intent locationIntent = new Intent(GroupActivity.this, ObservationActivity.class);
				locationIntent.putExtra(ITEMID, -1);
				locationIntent.putExtra("data",new String[]{});
				startActivityForResult(locationIntent, NEW);
				//$FALL-THROUGH$
			case R.id.menu_observation:
				showView(OBSERVATIONVIEW,currentState);
				break;
			case R.id.menu_save:
				if(groupView.isValid()){
					edit = false;
					
					Group g = id==-1?new Group(groupView.get()[0][ViewGroupMobArrayAdapter.NAME]):LivestockSolutions.getGroupByID(id);
					g.setName(groupView.get()[0][ViewGroupMobArrayAdapter.NAME]);
					g.setDescription(groupView.get()[0][ViewGroupMobArrayAdapter.DESCRIPTION]);
					
					id=g.getID();
					if(LivestockSolutions.addGroup(g)){
	        			Toast.makeText(this,getResources().getString(R.string.message_saved,getResources().getString(R.string.group)),Toast.LENGTH_SHORT).show();
	        		}else{
	        			Toast.makeText(this,getResources().getString(R.string.message_errorSave,getResources().getString(R.string.group),getResources().getString(R.string.message_unknown)),Toast.LENGTH_SHORT).show();
	        		}
					
					built=false;
					onPrepareOptionsMenu(menu);
					showView(currentState.getInt(STATEID,GROUPVIEW),currentState);
					// Pop current view
	        		stack.pop();
	        		// Pop edit change
	        		stack.pop();
					break;
				}
				//$FALL-THROUGH$
			default:
				return super.frameSelection(frame);
		}
		return true;
	}
	
	@Override
	public boolean constructFrame(int view) {
		switch (view) {
			case GROUPVIEW:
				setContentView(RESOURCEID[GROUPVIEW]);
				setPage();
				drawMembers();
				break;
			case OBSERVATIONVIEW:
				setContentView(RESOURCEID[OBSERVATIONVIEW]);
				setPage();
				drawObservations();
				break;
			case JOINVIEW:
	        	setContentView(RESOURCEID[JOINVIEW]);
	        	setPage();
	        	drawJoins();
	            break;
			default:
				return false;
		}
		return true;
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data){
		if(resultCode == RESULT_OK){
    		Group g = LivestockSolutions.getGroupByID(id);
    		int index = data.getIntExtra(ITEMID, -1);
    		String[] returned = data.getStringArrayExtra("data");
	    	switch (requestCode){
		    	case EXISTING:
		    		// If id does not exist then there must be an error!
		    		if(index>-1){
			    		observations.replace(returned, index);
			    		drawObservations();
			    		Observation[] bovineObservationList = g.getObservations();
			    		Observation observation = null;
			    		for(Observation o : bovineObservationList){
			    			if(o.getID() == Long.parseLong(returned[ViewObservationArrayAdapter.ID])){
			    				observation = o;
			    				observation.setComment(returned[ViewObservationArrayAdapter.VALUE]);
			    				observation.setPriority(Integer.parseInt(returned[ViewObservationArrayAdapter.TYPE]));
			    				break;
			    			}
			    		}
			    		if(observation!=null){
			    			g.addObservation(observation);
			    			LivestockSolutions.addGroup(g);
			    		}
		    		}else{
		    			Toast.makeText(this, getResources().getString(R.string.message_errorSave,R.string.observation,R.string.message_unexpectedReturn), Toast.LENGTH_SHORT).show();
		    		}
		    		break;
		    	case NEW:
		    		observations.add(returned);
		    		index = observations.getCount()-1;
		    		drawObservations();
    				g.addObservation(new Observation(
						new Date(Long.parseLong(returned[ViewObservationArrayAdapter.DATE])),
						returned[ViewObservationArrayAdapter.VALUE],
						Integer.parseInt(returned[ViewObservationArrayAdapter.TYPE])
					));
    				LivestockSolutions.addGroup(g);
		    		break;
	    	}
    	}
	}
	
	/**
	 * Set up the view to show the relevant content
	 */
	protected void setPage(){
		LinearLayout itemView = (LinearLayout) findViewById(R.id.listView);
		if(edit){
			((ViewGroupArrayAdapter) groupView).setModifyGroup();
	    }else{
	    	((ViewGroupArrayAdapter) groupView).setViewGroup();
	    }
		if(itemView != null){
			groupView.setRoot(itemView);
			itemView.addView(groupView.getView(0,null, itemView),0);
		}
	}
	
	/**
	 * Draw the list of Observations.<br>
	 * As these contain non-editable content, nothing can be in the middle of being altered.
	 * So the whole list can be re-drawn to show any changes.
	 */
	protected void drawObservations(){
		setupListTitle(R.id.selectiveListTitle, R.layout.list_item_observation);
		
		LinearLayout view = (LinearLayout) findViewById(R.id.selectiveList);
		view.removeAllViews();
		final ListObservationArrayAdapter listObservation = observations;
		if(listObservation.getCount()>0){
			listObservation.setRoot(view);
			for(int x=0; x< listObservation.getCount(); x++){
				View v = listObservation.getView(x, null, view);
				v.setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						Intent intent = new Intent(GroupActivity.this, ObservationActivity.class);
						intent.putExtra("data",observations.getItem(v.getId()));
						intent.putExtra(ITEMID, v.getId());
						startActivityForResult(intent, EXISTING);
					}
				});
				view.addView(v,x);
			}
		}else{
    		view.addView(inflateLayout(R.layout.item_none,view));
 		}
	}
	
	/**
	 * Draw the list of Members that belong in this GroupActivity.<br>
	 * As these contain non-editable content, nothing can be in the middle of being altered.
	 * So the whole list can be re-drawn to show any changes.
	 */
	protected void drawMembers(){
		setupListTitle(R.id.selectiveListTitle, R.layout.list_item_cattle);
		
		LinearLayout view = (LinearLayout) findViewById(R.id.selectiveList);
		view.removeAllViews();
		final ListCattleArrayAdapter listCattle = cattle;
		if(listCattle.getCount()>0){
			listCattle.setRoot(view);
			for(int x=0; x< listCattle.getCount(); x++){
				View v = listCattle.getView(x, null, view);
				v.setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						Intent intent = new Intent(GroupActivity.this, BovineActivity.class);
						intent.putExtra(ITEMID, Long.parseLong(cattle.getItem(v.getId())[ViewCattleArrayAdapter.ID]));
						startActivityForResult(intent, EXISTING);
					}
				});
				view.addView(v,x);
			}
		}else{
			view.addView(inflateLayout(R.layout.item_none,view));
		}
	}
	
	
    /**
     * Draw the list of Joins that belong in this Group.<br>
     * As these contain non-editable content, nothing can be in the middle of being altered.
     * So the whole list can be re-drawn to show any changes.
     */
    protected void drawJoins(){
    	setupListTitle(R.id.selectiveListTitle, R.layout.list_item_join);

    	LinearLayout view = (LinearLayout) findViewById(R.id.selectiveList);
    	view.removeAllViews();
    	final ListJoinArrayAdapter listJoin = joins;
    	if(listJoin.getCount()>0){
	    	listJoin.setRoot(view);
	    	for(int x=0; x< listJoin.getCount(); x++){
	    		View v = listJoin.getView(x, null, view);
	    		v.setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						Intent intent = new Intent(GroupActivity.this, JoinActivity.class);
						intent.putExtra(ITEMID, Long.parseLong(joins.getItem(v.getId())[ViewJoinArrayAdapter.ID]));
				    	startActivityForResult(intent, EXISTING);
					}
				});
	    		view.addView(v,x);
	    	}
	    }else{
			view.addView(inflateLayout(R.layout.item_none,view));
		}
    }
}
